#include <FlexiTimer2.h>
#include <Servo.h> 
//把TCS3200颜色传感器各控制引脚连到Arduino数字端口  
#define S0    A4   //物体表面的反射光越强，TCS3002D内置振荡器产生的方波频率越高，  
#define S1    A5  //S0和S1的组合决定输出信号频率比例因子，比例因子为2%  
                 //比率因子为TCS3200传感器OUT引脚输出信号频率与其内置振荡器频率之比  
#define S2     8   //S2和S3的组合决定让红、绿、蓝，哪种光线通过滤波器  
#define S3     3
#define OUT    2  //TCS3200颜色传感器输出信号连接到Arduino中断0引脚，并引发脉冲信号中断  
                  //在中断函数中记录TCS3200输出信号的脉冲个数
#define LED    A3 //控制TCS3200颜色传感器是否点亮LED

int   g_count = 0;  // 计算与反射光强相对应TCS3200颜色传感器输出信号的脉冲数  
int   g_array[3];   // 数组用于存储在1s内TCS3200输出信号的脉冲数
int   g_flag = 0;   // 滤波器模式选择顺序标志 
int   c_state = 0;     //颜色状态，绿球为0，红色为1,蓝色为2，默认为绿球

int   Interrupt_time =120;//一次识别的时间


void FilterColor(int Level01, int Level02);


void Count();

void Callback();

void WB(int Level0, int Level1);

void get_color();


//初始化  
void setup()  
{  
// 初始化TSC3200各控制引脚的输入输出模式  
//设置TCS3002D的内置振荡器方波频率与其输出信号频率的比例因子

  pinMode(S0, OUTPUT);  
  pinMode(S1, OUTPUT);  
  pinMode(S2, OUTPUT);  
  pinMode(S3, OUTPUT);  
  pinMode(OUT, INPUT);  
  pinMode(LED, OUTPUT);

  digitalWrite(S0, HIGH);   
  digitalWrite(S1, HIGH);
  attachInterrupt(0, Count, RISING);

  Serial.begin(9600); //启动串行通信
  delay(100);


  
}

void loop()  
{  
    get_color();
    delay(3000);
}  


//选择滤波器模式，决定让红、绿、蓝，哪种光线通过滤波器  
void FilterColor(int Level01, int Level02)  
{  
  if(Level01 != 0)  
    Level01 = HIGH;  
  if(Level02 != 0)  
    Level02 = HIGH;  
  digitalWrite(S2, Level01);  
  digitalWrite(S3, Level02);  
}  
   
//中断函数，计算TCS3200输出信号的脉冲数  
void Count()  
{  
  g_count ++ ;
} 
//定时器中断函数，每1s中断后，把该时间内的红、绿、蓝三种光线通过滤波器时，  
//TCS3200输出信号脉冲个数分别存储到数组g_array[3]的相应元素变量中  
void Callback()  
{  
  switch(g_flag)
  {  
    case 0:  
         Serial.println("正在颜色识别");  
         WB(LOW, LOW);   //选择让红色光线通过滤波器的模式  
         break;  
    case 1:  
         Serial.print("0.3秒内红色脉冲数：");  
         Serial.println(g_count);   //打印红光通过滤波器时，TCS3200输出的脉冲个数  
         g_array[0] = g_count;    //存储红光通过滤波器时，TCS3200输出的脉冲个数  
         WB(HIGH, HIGH);  //选择让绿色光线通过滤波器的模式  
         break;  
    case 2:  
         Serial.print("0.3秒内绿色脉冲数：");  
         Serial.println(g_count);   //打印绿光通过滤波器时，TCS3200输出的脉冲个数  
         g_array[1] = g_count ;    //存储绿光通过滤波器时，TCS3200输出的脉冲个数  
         WB(LOW, HIGH);  //选择让蓝色光线通过滤波器的模式  
         break;  
   
    case 3:  
         Serial.print("0.3秒内蓝色脉冲数");  
         Serial.println(g_count);   //打印蓝光通过滤波器时，TCS3200输出的脉冲个数  
         Serial.println("颜色识别结束");  
         g_array[2] = g_count +300;     //存储蓝光通过滤波器时，TCS3200输出的脉冲个数  
         WB(HIGH, LOW);   //选择无滤波器的模式    
         break;  
   default:  
         g_count = 0;     //计数值清零  
         break;  
  }  
}  



//设置反射光中红、绿、蓝三色光分别通过滤波器时如何处理数据的标志  
//该函数被Callback( )调用  
void WB(int Level0, int Level1)      
{  
  g_count = 0;   //计数值清零  
  g_flag ++;     //输出信号计数标志  
  FilterColor(Level0, Level1); //滤波器模式  
}



void get_color()
{
  int turns = 1;
  Serial.println("开始识别颜色！打开LED补光灯！");
  int red_num =0;
  int gre_num =0;
  int blu_num =0;
  digitalWrite(LED, HIGH);//点亮LED灯
  FlexiTimer2::set(Interrupt_time/4,Callback);
  FlexiTimer2::start();//定时器中断开
  	for(int i =1;i<=turns;i++)
  	{
  		g_flag = 0;  
   		delay(Interrupt_time);//一次识别时间为Interrupt_time
	   if((g_array[0] > g_array[1]) && (g_array[0] > g_array[2]))
	   {
	    red_num++;
	   }
	    else if((g_array[2] > g_array[1]) && (g_array[2] > g_array[0]) )
	   {
	     blu_num++;
	   }
	    else
	   {
	     gre_num++;
	   }
	}
    
 FlexiTimer2::stop();//定时器中断关
	 if(red_num>blu_num && red_num>gre_num)
	 {
	 	Serial.println("   识别结果为红色小球！");
	 	c_state = 1;
	 } 
	 else if(blu_num>red_num && blu_num>gre_num)
	 {
	 	Serial.println("   识别结果为蓝色小球！");
	 	c_state = 2;
	 }
	 else
	 {
	 	Serial.println("  识别结果为绿色小球！");
	 	c_state = 0;
	 } 
   Serial.println("识别颜色结束，关闭LED补光灯！"); 
   digitalWrite(LED, LOW);//关闭LED灯
}
